package com.trace.demo.controller;

import com.trace.demo.entity.Dealer;
import com.trace.demo.entity.DistributionInfo;
import com.trace.demo.entity.User;
import com.trace.demo.repository.DealerRepository;
import com.trace.demo.repository.DistributionInfoRepository;
import com.trace.demo.repository.UserRepository;
import com.trace.demo.response.ApiResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/api/distribution")
public class DistributionInfoController {

    @Autowired
    private DistributionInfoRepository distributionInfoRepository;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private DealerRepository dealerRepository;
    
    /**
     * 获取所有分销信息（分页）
     * 
     * @param page 页码
     * @param size 每页大小
     * @param sort 排序字段
     * @param direction 排序方向
     * @param keyword 关键词搜索
     * @param fromDate 起始日期
     * @param toDate 截止日期
     * @return 分页分销信息列表
     */
    @GetMapping
    public ResponseEntity<ApiResponse<Map<String, Object>>> getAllDistributionInfo(
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size,
            @RequestParam(defaultValue = "distributionDate") String sort,
            @RequestParam(defaultValue = "desc") String direction,
            @RequestParam(required = false) String keyword,
            @RequestParam(required = false) LocalDate fromDate,
            @RequestParam(required = false) LocalDate toDate) {
        
        try {
            // 创建排序对象
            Sort.Direction sortDirection = "desc".equalsIgnoreCase(direction) ? Sort.Direction.DESC : Sort.Direction.ASC;
            Sort sortObj = Sort.by(sortDirection, sort);
            
            // 创建分页对象
            PageRequest pageRequest = PageRequest.of(page, size, sortObj);
            
            // 查询分销信息列表
            Page<DistributionInfo> distributionInfoPage;
            
            if (keyword != null && !keyword.isEmpty()) {
                // 根据关键词搜索来源地、目的地或批次ID
                distributionInfoPage = distributionInfoRepository.findByFromLocationContainingOrToLocationContainingOrBatchIdContaining(
                        keyword, keyword, keyword, pageRequest);
            } else if (fromDate != null && toDate != null) {
                // 根据日期范围查询
                distributionInfoPage = distributionInfoRepository.findByDistributionDateBetween(
                        fromDate, toDate, pageRequest);
            } else if (fromDate != null) {
                // 根据起始日期查询
                distributionInfoPage = distributionInfoRepository.findByDistributionDateGreaterThanEqual(
                        fromDate, pageRequest);
            } else {
                // 无过滤条件
                distributionInfoPage = distributionInfoRepository.findAll(pageRequest);
            }
            
            // 构建响应数据
            Map<String, Object> responseData = new HashMap<>();
            responseData.put("content", distributionInfoPage.getContent());
            responseData.put("totalElements", distributionInfoPage.getTotalElements());
            responseData.put("totalPages", distributionInfoPage.getTotalPages());
            responseData.put("currentPage", distributionInfoPage.getNumber());
            responseData.put("size", distributionInfoPage.getSize());
            
            return ResponseEntity.ok(new ApiResponse<>(true, "获取分销信息列表成功", responseData));
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(new ApiResponse<>(false, "获取分销信息列表失败: " + e.getMessage(), null));
        }
    }

    /**
     * 保存分销信息
     * 
     * @param dealerId 经销商ID
     * @param distributionInfo 分销信息
     * @return 保存的分销信息
     */
    @PostMapping("/entry")
    public ResponseEntity<ApiResponse<DistributionInfo>> saveDistributionInfo(
            @RequestParam Long dealerId,
            @RequestBody DistributionInfo distributionInfo) {

        Optional<Dealer> dealerOptional = dealerRepository.findById(dealerId);
        if (!dealerOptional.isPresent()) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND)
                    .body(new ApiResponse<>(false, "Dealer not found with id: " + dealerId, null));
        }

        Dealer dealer = dealerOptional.get();
        distributionInfo.setDealer(dealer);
        distributionInfo.setUser(dealer.getUser());

        // 生成批次ID，如果没有提供
        if (distributionInfo.getBatchId() == null || distributionInfo.getBatchId().isEmpty()) {
            String batchId = "DIST-" + UUID.randomUUID().toString().substring(0, 8).toUpperCase();
            distributionInfo.setBatchId(batchId);
        }
        
        // 设置创建和更新时间
        LocalDateTime now = LocalDateTime.now();
        distributionInfo.setCreatedAt(now);
        distributionInfo.setUpdatedAt(now);

        DistributionInfo savedDistributionInfo = distributionInfoRepository.save(distributionInfo);
        return ResponseEntity.status(HttpStatus.CREATED)
                .body(new ApiResponse<>(true, "Distribution information saved successfully", savedDistributionInfo));
    }
    
    /**
     * 批量保存分销信息
     * 
     * @param dealerId 经销商ID
     * @param distributionInfoList 分销信息列表
     * @return 保存结果
     */
    @PostMapping("/batch/entry")
    @Transactional
    public ResponseEntity<ApiResponse<List<DistributionInfo>>> batchSaveDistributionInfo(
            @RequestParam Long dealerId,
            @RequestBody List<DistributionInfo> distributionInfoList) {

        try {
            Optional<Dealer> dealerOptional = dealerRepository.findById(dealerId);
            if (!dealerOptional.isPresent()) {
                return ResponseEntity.status(HttpStatus.NOT_FOUND)
                        .body(new ApiResponse<>(false, "Dealer not found with id: " + dealerId, null));
            }

            Dealer dealer = dealerOptional.get();
            User user = dealer.getUser();
            LocalDateTime now = LocalDateTime.now();
            
            // 设置每个分销信息的经销商和用户信息
            distributionInfoList.forEach(info -> {
                info.setDealer(dealer);
                info.setUser(user);
                
                // 生成批次ID，如果没有提供
                if (info.getBatchId() == null || info.getBatchId().isEmpty()) {
                    String batchId = "DIST-" + UUID.randomUUID().toString().substring(0, 8).toUpperCase();
                    info.setBatchId(batchId);
                }
                
                // 设置创建和更新时间
                info.setCreatedAt(now);
                info.setUpdatedAt(now);
            });
            
            List<DistributionInfo> savedDistributionInfoList = distributionInfoRepository.saveAll(distributionInfoList);
            
            return ResponseEntity.status(HttpStatus.CREATED)
                    .body(new ApiResponse<>(true, "Batch distribution information saved successfully", savedDistributionInfoList));
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(new ApiResponse<>(false, "Error saving batch distribution information: " + e.getMessage(), null));
        }
    }

    /**
     * 根据ID获取分销信息
     * 
     * @param id 分销信息ID
     * @return 分销信息详情
     */
    @GetMapping("/{id}")
    public ResponseEntity<ApiResponse<DistributionInfo>> getDistributionInfoById(@PathVariable Long id) {
        Optional<DistributionInfo> distributionInfo = distributionInfoRepository.findById(id);
        return distributionInfo.map(value -> ResponseEntity.ok(new ApiResponse<>(true, "Distribution information retrieved successfully", value)))
                .orElseGet(() -> ResponseEntity.status(HttpStatus.NOT_FOUND)
                        .body(new ApiResponse<>(false, "Distribution information not found with id: " + id, null)));
    }

    /**
     * 根据经销商ID获取分销信息（分页）
     * 
     * @param dealerId 经销商ID
     * @param page 页码
     * @param size 每页大小
     * @param sort 排序字段
     * @param direction 排序方向
     * @return 分销信息列表
     */
    @GetMapping("/dealer/{dealerId}")
    public ResponseEntity<ApiResponse<Map<String, Object>>> getDistributionInfoByDealerId(
            @PathVariable Long dealerId,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size,
            @RequestParam(defaultValue = "distributionDate") String sort,
            @RequestParam(defaultValue = "desc") String direction) {
        
        try {
            Optional<Dealer> dealerOptional = dealerRepository.findById(dealerId);
            if (!dealerOptional.isPresent()) {
                return ResponseEntity.status(HttpStatus.NOT_FOUND)
                        .body(new ApiResponse<>(false, "Dealer not found with id: " + dealerId, null));
            }
            
            // 创建排序对象
            Sort.Direction sortDirection = "desc".equalsIgnoreCase(direction) ? Sort.Direction.DESC : Sort.Direction.ASC;
            Sort sortObj = Sort.by(sortDirection, sort);
            
            // 创建分页对象
            PageRequest pageRequest = PageRequest.of(page, size, sortObj);
            
            // 查询经销商的分销信息列表
            Page<DistributionInfo> distributionInfoPage = distributionInfoRepository.findByDealerId(dealerId, pageRequest);
            
            // 构建响应数据
            Map<String, Object> responseData = new HashMap<>();
            responseData.put("content", distributionInfoPage.getContent());
            responseData.put("totalElements", distributionInfoPage.getTotalElements());
            responseData.put("totalPages", distributionInfoPage.getTotalPages());
            responseData.put("currentPage", distributionInfoPage.getNumber());
            responseData.put("size", distributionInfoPage.getSize());
            
            return ResponseEntity.ok(new ApiResponse<>(true, "Distribution information retrieved successfully", responseData));
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(new ApiResponse<>(false, "Error retrieving distribution information: " + e.getMessage(), null));
        }
    }

    /**
     * 根据批次ID获取分销信息
     * 
     * @param batchId 批次ID
     * @return 分销信息列表
     */
    @GetMapping("/batch/{batchId}")
    public ResponseEntity<ApiResponse<List<DistributionInfo>>> getDistributionInfoByBatchId(@PathVariable String batchId) {
        List<DistributionInfo> distributionInfoList = distributionInfoRepository.findByBatchId(batchId);
        if (distributionInfoList.isEmpty()) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND)
                    .body(new ApiResponse<>(false, "No distribution information found with batch id: " + batchId, null));
        }

        return ResponseEntity.ok(new ApiResponse<>(true, "Distribution information retrieved successfully", distributionInfoList));
    }

    /**
     * 更新分销信息
     * 
     * @param id 分销信息ID
     * @param distributionInfo 更新的分销信息
     * @return 更新后的分销信息
     */
    @PutMapping("/{id}")
    public ResponseEntity<ApiResponse<DistributionInfo>> updateDistributionInfo(
            @PathVariable Long id,
            @RequestBody DistributionInfo distributionInfo) {

        Optional<DistributionInfo> existingDistributionInfoOptional = distributionInfoRepository.findById(id);
        if (!existingDistributionInfoOptional.isPresent()) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND)
                    .body(new ApiResponse<>(false, "Distribution information not found with id: " + id, null));
        }
        
        DistributionInfo existingDistributionInfo = existingDistributionInfoOptional.get();

        // 保留原始信息
        distributionInfo.setId(id);
        distributionInfo.setCreatedAt(existingDistributionInfo.getCreatedAt());
        distributionInfo.setUser(existingDistributionInfo.getUser());
        distributionInfo.setDealer(existingDistributionInfo.getDealer());
        distributionInfo.setUpdatedAt(LocalDateTime.now());
        
        // 如果批次ID为空，则保留原来的
        if (distributionInfo.getBatchId() == null || distributionInfo.getBatchId().isEmpty()) {
            distributionInfo.setBatchId(existingDistributionInfo.getBatchId());
        }

        DistributionInfo updatedDistributionInfo = distributionInfoRepository.save(distributionInfo);
        return ResponseEntity.ok(new ApiResponse<>(true, "Distribution information updated successfully", updatedDistributionInfo));
    }

    /**
     * 删除分销信息
     * 
     * @param id 分销信息ID
     * @return 删除结果
     */
    @DeleteMapping("/{id}")
    public ResponseEntity<ApiResponse<Void>> deleteDistributionInfo(@PathVariable Long id) {
        Optional<DistributionInfo> distributionInfo = distributionInfoRepository.findById(id);
        if (!distributionInfo.isPresent()) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND)
                    .body(new ApiResponse<>(false, "Distribution information not found with id: " + id, null));
        }

        distributionInfoRepository.deleteById(id);
        return ResponseEntity.ok(new ApiResponse<>(true, "Distribution information deleted successfully", null));
    }
    
    /**
     * 批量删除分销信息
     * 
     * @param ids 分销信息ID列表
     * @return 删除结果
     */
    @DeleteMapping("/batch")
    @Transactional
    public ResponseEntity<ApiResponse<Void>> batchDeleteDistributionInfo(@RequestBody List<Long> ids) {
        try {
            if (ids == null || ids.isEmpty()) {
                return ResponseEntity.status(HttpStatus.BAD_REQUEST)
                        .body(new ApiResponse<>(false, "Distribution information ID list cannot be empty", null));
            }
            
            // 检查所有ID是否存在
            List<DistributionInfo> foundInfos = distributionInfoRepository.findAllById(ids);
            if (foundInfos.size() != ids.size()) {
                List<Long> foundIds = foundInfos.stream().map(DistributionInfo::getId).collect(Collectors.toList());
                List<Long> notFoundIds = ids.stream().filter(id -> !foundIds.contains(id)).collect(Collectors.toList());
                
                return ResponseEntity.status(HttpStatus.NOT_FOUND)
                        .body(new ApiResponse<>(false, "Following distribution information IDs not found: " + notFoundIds, null));
            }
            
            // 执行批量删除
            distributionInfoRepository.deleteAllById(ids);
            
            return ResponseEntity.ok(new ApiResponse<>(true, "Batch deletion successful", null));
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(new ApiResponse<>(false, "Error during batch deletion: " + e.getMessage(), null));
        }
    }
    
    /**
     * 按日期范围统计分销信息
     * 
     * @param fromDate 起始日期
     * @param toDate 截止日期
     * @return 统计结果
     */
    @GetMapping("/statistics/date-range")
    public ResponseEntity<ApiResponse<Map<String, Object>>> getDistributionStatsByDateRange(
            @RequestParam(required = false) LocalDate fromDate,
            @RequestParam(required = false) LocalDate toDate) {
        
        try {
            Map<String, Object> statistics = new HashMap<>();
            
            // 根据日期范围统计
            if (fromDate != null && toDate != null) {
                long count = distributionInfoRepository.countByDistributionDateBetween(fromDate, toDate);
                statistics.put("count", count);
                statistics.put("fromDate", fromDate);
                statistics.put("toDate", toDate);
            } else if (fromDate != null) {
                long count = distributionInfoRepository.countByDistributionDateGreaterThanEqual(fromDate);
                statistics.put("count", count);
                statistics.put("fromDate", fromDate);
            } else if (toDate != null) {
                long count = distributionInfoRepository.countByDistributionDateLessThanEqual(toDate);
                statistics.put("count", count);
                statistics.put("toDate", toDate);
            } else {
                long totalCount = distributionInfoRepository.count();
                statistics.put("totalCount", totalCount);
            }
            
            return ResponseEntity.ok(new ApiResponse<>(true, "Statistics retrieved successfully", statistics));
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(new ApiResponse<>(false, "Error retrieving statistics: " + e.getMessage(), null));
        }
    }
}
